package com.googlecode.curvedmetromaps.core.logic.forcedriven;

import org.jbox2d.common.Vec2;

import com.googlecode.curvedmetromaps.core.logic.bezier.BSplineCurveFit;

public class MetroLineToBSpline {

	public static Vec2[] fit(Vec2[] samples, int degree, int numCtrlPoint) {
		if (samples.length == 0) {
			return null;
		} else if (samples.length == 1) {
			Vec2[] v = { new Vec2(samples[0]) };
			return v;
		} else {
			// Flatten station coordinates to a single array
			double[] sampleArray = new double[samples.length * 2];
			for (int i = 0; i < samples.length; i++) {
				sampleArray[2 * i] = samples[i].x;
				sampleArray[2 * i + 1] = samples[i].y;
			}

			// Fit B-Spline curve to stations
			BSplineCurveFit mSpline = new BSplineCurveFit(2, samples.length, sampleArray, degree, numCtrlPoint);

			// Convert result to array of vectors
			Vec2[] spline = new Vec2[samples.length];
			double mult = 1.0 / (spline.length - 1);
			for (int i = 0; i < spline.length; i++) {
				double t = mult * (double) i;
				double[] p = mSpline.GetPosition(t);
				spline[i] = new Vec2((float) p[0], (float) p[1]);
			}
			return spline;
		}
	}

}
